pvh: use PV handlers for PIO
authorGeorge Dunlap <george.dunlap@eu.citrix.com>
Wed, 13 Nov 2013 08:40:03 +0000 (09:40 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 13 Nov 2013 08:40:03 +0000 (09:40 +0100)
Register an IO handler for the entire PIO range, and have it call the
PV PIO handlers.

NB at this point this won't do the full "copy and execute on the stack
with full GPRs" work-around; this may need to be sorted out for dom0 to allow
these instructions to happen in guest context.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Acked-by: Eddie Dong <eddie.dong@intel.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/traps.c
xen/include/asm-x86/traps.h

index 4bd4372acd69570dabf62b48f816c0a864618f95..3919590333a02960c998e6eeb6636bfc60e0ea17 100644 (file)
@@ -519,6 +519,20 @@ static int hvm_print_line(
     return X86EMUL_OKAY;
 }
 
+static int handle_pvh_io(
+    int dir, uint32_t port, uint32_t bytes, uint32_t *val)
+{
+    struct vcpu *curr = current;
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+    if ( dir == IOREQ_WRITE )
+        guest_io_write(port, bytes, *val, curr, regs);
+    else
+        *val = guest_io_read(port, bytes, curr, regs);
+
+    return X86EMUL_OKAY;
+}
+
 int hvm_domain_initialise(struct domain *d)
 {
     int rc;
@@ -566,7 +580,10 @@ int hvm_domain_initialise(struct domain *d)
     d->arch.hvm_domain.io_handler->num_slot = 0;
 
     if ( is_pvh_domain(d) )
+    {
+        register_portio_handler(d, 0, 0x10003, handle_pvh_io);
         return 0;
+    }
 
     hvm_init_guest_time(d);
 
index 4b2c2ea8f40f142b62a14ec0326ef2d43538abee..e5b358504d8bdb1f6272d74e65d4e1b9ff19a8b3 100644 (file)
@@ -1671,7 +1671,7 @@ static int pci_cfg_ok(struct domain *d, int write, int size)
     return 1;
 }
 
-static uint32_t guest_io_read(
+uint32_t guest_io_read(
     unsigned int port, unsigned int bytes,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
@@ -1738,7 +1738,7 @@ static uint32_t guest_io_read(
     return data;
 }
 
-static void guest_io_write(
+void guest_io_write(
     unsigned int port, unsigned int bytes, uint32_t data,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
index 82cbcee1603ea00af0eeb41c3cfd74d118821407..556b133f27e36d66203ec34a58525c93c914ef45 100644 (file)
@@ -49,4 +49,9 @@ extern int guest_has_trap_callback(struct domain *d, uint16_t vcpuid,
 extern int send_guest_trap(struct domain *d, uint16_t vcpuid,
                                unsigned int trap_nr);
 
+uint32_t guest_io_read(unsigned int port, unsigned int bytes,
+                       struct vcpu *, struct cpu_user_regs *);
+void guest_io_write(unsigned int port, unsigned int bytes, uint32_t data,
+                    struct vcpu *, struct cpu_user_regs *);
+
 #endif /* ASM_TRAP_H */